using System;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.OracleClient;
using System.Xml;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using Microsoft.Win32;
using System.IO;
using System.Collections.Generic;
using System.Drawing;

namespace Srvtools
{
    [ToolboxBitmap(typeof(InfoComboBox), "Resources.InfoComboBox.ico")]
    public partial class InfoComboBox : ComboBox, ISupportInitialize, IUseSelectCommand//, IGetDbConnectionStringAlias
	{

        public void BeginInit()
        {

        }

        public void EndInit()
        {
            if (this.SelectCommand != null && this.SelectCommand != "")
            {
                if (this.SelectTop != null && this.SelectTop != "")
                {
                    StringBuilder sb = new StringBuilder(this.SelectCommand);
                    if (this.SelectCommand.IndexOf(" top ") != -1)
                    {
                        string oldValue = "";
                        string[] parts = this.SelectCommand.Split(' ');
                        int i = parts.Length;
                        for (int j = 0; j < i; j++)
                        {
                            if (parts[j].ToLower() == "top" && j != i - 1)
                            {
                                oldValue = parts[j + 1];
                                break;
                            }
                        }
                        if (oldValue != "")
                        {
                            int lenth = this.SelectCommand.IndexOf(oldValue) + oldValue.Length;
                            sb.Replace(oldValue, this.SelectTop, 0, lenth);
                        }
                    }
                    else
                    {
                        sb.Insert(this.SelectCommand.Trim().ToLower().IndexOf("select") + 6, " top " + this.SelectTop);
                    }
                    this.SelectCommand = sb.ToString();
                }
                if (this.Site == null)
                {
                    InnerDs.RemoteName = "GLModule.cmdRefValUse";
                    InnerDs.Execute(this.SelectCommand, true);

                    InnerBs.DataSource = InnerDs;
                    InnerBs.DataMember = "cmdRefValUse";
                    this.DataSource = InnerBs;
                }
            }
        }

        public InfoComboBox()
		{
			InitializeComponent();

			this.DropDown += new EventHandler(DropDownHappened);
			this.DropDownClosed += new EventHandler(DropDownClosedHappened);
            this.Enter += new EventHandler(EnterHappened);
            this.Leave += new EventHandler(LeaveHappened);

            this.KeyDown += delegate(object sender, KeyEventArgs e)
            {
                BindingSourceBeginEdit();
            };
            language = CliSysMegLag.GetClientLanguage();
		}

        private void BindingSourceBeginEdit()
        {
            Binding TextBinding = this.DataBindings["Text"];
            Binding SelectedValueBinding = this.DataBindings["SelectedValue"];
            if (TextBinding != null)
            {
                InfoBindingSource bindingSource = TextBinding.DataSource as InfoBindingSource;
                if (bindingSource != null)
                {
                    bindingSource.BeginEdit();
                }
            }
            if (SelectedValueBinding != null)
            {
                InfoBindingSource bindingSource = SelectedValueBinding.DataSource as InfoBindingSource;
                if (bindingSource != null)
                {
                    bindingSource.BeginEdit();
                }
            }
        }

        private SYS_LANGUAGE language;
		private DataColumn column;
        private DataTable table;
        private string oldDisplayMember = "";

        public object GetDataSource()
        {
            object obj = new object();
            if (this.SelectCommand != null && this.SelectCommand != "")
            {
                obj = this.InnerDs;
            }
            else
            {
                obj = this.DataSource;
                while (!(obj is InfoDataSet))
                {
                    if (obj is InfoBindingSource)
                    {
                        obj = ((InfoBindingSource)obj).DataSource;
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            return obj;
        }

        public string GetDataMember()
        {
            string strDataMember = "";
            object obj = this.DataSource;
            if (obj is InfoDataSet && this.ValueMember.IndexOf('.') >= 0)
            {
                strDataMember = this.ValueMember.Substring(0, this.ValueMember.IndexOf('.'));
            }
            else
            {
                while (strDataMember == "")
                {
                    if (obj is InfoBindingSource)
                    {
                        strDataMember = ((InfoBindingSource)obj).DataMember.ToString();
                        obj = ((InfoBindingSource)obj).DataSource;
                    }
                }
            }
            return strDataMember;
        }

        public string GetDataTable()
        {
            string strTableName = "";
            if (this.SelectCommand != null && this.SelectCommand != "")
            {
                strTableName = this.InnerDs.RemoteName;
                strTableName = strTableName.Substring(strTableName.IndexOf('.') + 1);
            }
            else
            {
                strTableName = this.GetDataMember();
                InfoDataSet infoDs = (InfoDataSet)this.GetDataSource();
                if (infoDs != null)
                {
                    if (infoDs.RealDataSet.Relations != null)
                    {
                        int i = infoDs.RealDataSet.Relations.Count;
                        for (int j = 0; j < i; j++)
                        {
                            if (infoDs.RealDataSet.Relations[j].RelationName == strTableName)
                            {
                                strTableName = infoDs.RealDataSet.Relations[j].ChildTable.TableName;
                                break;
                            }
                        }
                    }
                }
            }
            return strTableName;
        }

        private void DropDownHappened(object sender, EventArgs e)
        {
            if (this.Expression != null && this.Expression != "")
            {
                table = new DataTable();
                table.TableName = this.GetDataTable();
                column = new DataColumn();
                column.Expression = this.Expression;
                column.ColumnName = this.Expression;
                InfoDataSet ds = (InfoDataSet)this.GetDataSource();
                if (!ds.RealDataSet.Tables[table.TableName].Columns.Contains(column.ColumnName))
                {
                    ds.RealDataSet.Tables[table.TableName].Columns.Add(column);
                }
                else
                {
                    bExpColExist = true;
                }

                oldDisplayMember = this.DisplayMember;
                if (this.DataSource is InfoDataSet)
                    this.DisplayMember = table.TableName + "." + this.Expression;
                else if (this.DataSource is InfoBindingSource)
                    this.DisplayMember = this.Expression;
            }
        }

        bool bExpColExist = false;
		private void DropDownClosedHappened(object sender, EventArgs e)
		{
            if (this.Expression != null && this.Expression != "")
            {
                int index = base.SelectedIndex;
                if (!bExpColExist)
                {
                    ((InfoDataSet)this.GetDataSource()).RealDataSet.Tables[table.TableName].Columns.Remove(column.ColumnName);
                }

                this.DisplayMember = oldDisplayMember;
                if (base.SelectedIndex != index)
                {
                    base.SelectedIndex = index;
                    BindingSourceBeginEdit();
                }
            }
        }

        private string DisplayMemberBeforeEnter;
        private void EnterHappened(object sender, EventArgs e)
        {
            DisplayMemberBeforeEnter = this.DisplayMember;
            this.DisplayMember = this.ValueMember;
        }

        private void LeaveHappened(object sender, EventArgs e)
        {
            if (this.DataBindings["SelectedValue"] != null)
            {
                this.SelectedValue = this.Text;
                this.DataBindings["SelectedValue"].WriteValue();
            }
            this.DisplayMember = DisplayMemberBeforeEnter;
        }

		private string expr;

		[Category("Data")]
		public string Expression
		{
			get
			{
				return expr;
			}
			set
			{
				expr = value;
			}
		}

        public new object SelectedValue
        {
            get
            {
                return base.SelectedValue;
            }
            set
            {
                base.SelectedValue = value;

                if (this.DataBindings["SelectedValue"] != null)
                {
                    this.DataBindings["SelectedValue"].DataSourceUpdateMode = DataSourceUpdateMode.Never;
                }
            }
        }

        internal InfoDataSet InnerDs = new InfoDataSet();
        internal InfoBindingSource InnerBs = new InfoBindingSource();

        private string _SelectAlias;
        [Category("Data"), Editor(typeof(ComboConnectionEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string SelectAlias
        {
            get
            {
                return _SelectAlias;
            }
            set
            {
                _SelectAlias = value;
            }
        }

        private string _SelectTop;
        [Category("Data")]
        public string SelectTop
        {
            get
            {
                return _SelectTop;
            }
            set
            {
                _SelectTop = value;
            }
        }

        private string _SelectCommand;
        [Editor(typeof(SelectCommandEditor), typeof(System.Drawing.Design.UITypeEditor))]
        [Category("Data")]
        public string SelectCommand
        {
            get
            {
                return _SelectCommand;
            }
            set
            {
                _SelectCommand = value;
                if (this.Site != null && _SelectAlias != null && _SelectAlias != "" && _SelectCommand != null && _SelectCommand != "")
                {
                    /*IDbConnection nwindConn = AllocateConnection(_ConnectionType);
                    InfoCommand cmd = new InfoCommand();
                    cmd.CommandText = _SelectCommand;
                    cmd.Connection = nwindConn;

                    IDbDataAdapter da = AllocateDataAdapter(_ConnectionType);
                    da.SelectCommand = cmd.GetInternalCommand();
                    DataSet ds = new DataSet();
                    da.Fill(ds);
                    InnerBs.DataSource = ds;
                    InnerBs.DataMember = ds.Tables[0].TableName;
                    this.DataSource = InnerBs;*/
                    InnerDs.RemoteName = "GLModule.cmdRefValUse";
                    InnerDs.Execute(_SelectCommand, _SelectAlias, true);
                    InnerBs.DataSource = InnerDs;
                    InnerBs.DataMember = "cmdRefValUse";
                    this.DataSource = InnerBs;
                }
            }
        }

        /*private string _ConnectionType;
        [Browsable(false)]
        public string ConnectionType
        {
            get { return _ConnectionType; }
            set { _ConnectionType = value; }
        }

        private IDbConnection AllocateConnection(string ConnectionType)
        {
            IDbConnection con = null;
            switch (ConnectionType)
            {
                case "1":
                    con = new SqlConnection(_SelectAlias);
                    break;
                case "2":
                    con = new OleDbConnection(_SelectAlias);
                    break;
                case "3":
                    con = new OracleConnection(_SelectAlias);
                    break;
                case "4":
                    con = new OdbcConnection(_SelectAlias);
                    break;
            }
            return con;
        }

        private IDbDataAdapter AllocateDataAdapter(string ConnectionType)
        {
            IDbDataAdapter da = null;
            switch (ConnectionType)
            {
                case "1":
                    da = new SqlDataAdapter();
                    break;
                case "2":
                    da = new OleDbDataAdapter();
                    break;
                case "3":
                    da = new OracleDataAdapter();
                    break;
                case "4":
                    da = new OdbcDataAdapter();
                    break;
            }
            return da;
        }

        public String FindConnectionString(String aliasName)
        {
            String xmlName = GetServerPath() + "DB.xml";
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlName);

            XmlNode node = xmlDoc.FirstChild.FirstChild.SelectSingleNode(aliasName);

            string DbString = node.Attributes["String"].Value.Trim();
            string Pwd = GetPwdString(node.Attributes["Password"].Value.Trim());
            if (DbString.Length > 0 && Pwd.Length > 0)
            {
                if (DbString[DbString.Length - 1] != ';')
                    DbString = DbString + ";Password=" + Pwd;
                else
                    DbString = DbString + "Password=" + Pwd;
            }
            return DbString;
        }

        public String[] GetDbConnectionStringAlias()
        {
            List<String> aliasList = new List<String>();

            String xmlName = GetServerPath() + "DB.xml";
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlName);

            XmlNodeList nodeList = xmlDoc.FirstChild.FirstChild.ChildNodes;
            foreach (XmlNode n in nodeList)
            {
                aliasList.Add(n.Name);
            }

            return aliasList.ToArray();
        }

        private static String _serverPath;
        private static string GetServerPath()
        {
            if (_serverPath == null || _serverPath.Length == 0)
            {
                RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE\\infolight\\eep.net");
                String s = (String)rk.GetValue("Server Path");
                rk.Close();

                if (s[s.Length - 1] != '\\') s = s + "\\";

                _serverPath = s;
            }
            return _serverPath;
        }

        private string GetPwdString(string s)
        {
            string sRet = "";
            for (int i = 0; i < s.Length; i++)
            {
                sRet = sRet + (char)(((int)(s[s.Length - 1 - i])) ^ s.Length);
            }
            return sRet;
        }*/
	}

    public class ComboCommandTextEditor : System.Drawing.Design.UITypeEditor
    {
        public ComboCommandTextEditor()
        {
        }

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        // Displays the UI for value selection.
        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            // Uses the IWindowsFormsEditorService to display a drop-down UI in the Properties window.
            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

            InfoComboBox combo = (InfoComboBox)context.Instance;
            IDbConnection con = null;
            /*switch (combo.ConnectionType)
            {
                case "1":
                    con = new SqlConnection(combo.SelectAlias);
                    break;
                case "2":
                    con = new OleDbConnection(combo.SelectAlias);
                    break;
                case "3":
                    con = new OracleConnection(combo.SelectAlias);
                    break;
                case "4":
                    con = new OdbcConnection(combo.SelectAlias);
                    break;
            }*/
            String commandText = "";
            if (con != null)
            {
                CommandTextOptionDialog dialog = new CommandTextOptionDialog(con, combo.SelectCommand);
                edSvc.ShowDialog(dialog);
                commandText = dialog.CommandText;
                dialog.Dispose();
            }
            return commandText;
        }
    }

    public class ComboConnectionEditor : System.Drawing.Design.UITypeEditor
    {
        public ComboConnectionEditor()
        {
        }

        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }

        // Displays the UI for value selection.
        [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            IWindowsFormsEditorService EditorService = null;
            if (provider != null)
            {
                EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
            }

            if (EditorService != null)
            {
                ListBox ColumnList = new ListBox();
                ColumnList.SelectionMode = SelectionMode.One;
                InfoComboBox combo = context.Instance as InfoComboBox;
                if (combo != null)
                {
                    RegistryKey rk = Registry.LocalMachine.OpenSubKey("SOFTWARE\\infolight\\eep.net");
                    String s = (String)rk.GetValue("Server Path");
                    if (s[s.Length - 1] != '\\') s = s + "\\DB.xml";
                    rk.Close();
                    XmlDocument DBXML = new XmlDocument();
                    if (File.Exists(s))
                    {
                        DBXML.Load(s);
                        XmlNode aNode = DBXML.DocumentElement.FirstChild;

                        while (aNode != null)
                        {
                            if (aNode.Name.ToUpper().Equals("DATABASE"))
                            {
                                XmlNode bNode = aNode.FirstChild;
                                while (bNode != null)
                                {
                                    ColumnList.Items.Add(bNode.LocalName);
                                    bNode = bNode.NextSibling;
                                }
                            }
                            aNode = aNode.NextSibling;
                        }
                    }
                }
                ColumnList.SelectedIndexChanged += delegate(object sender, EventArgs e)
                {
                    int index = ColumnList.SelectedIndex;
                    if (index != -1)
                    {
                        value = ColumnList.Items[index].ToString();
                    }
                    EditorService.CloseDropDown();
                };
                EditorService.DropDownControl(ColumnList);
            }
            return value;
        }
    }
}